package com.turkcell.dv.rest;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.eolcum.evocenter.Action;
import com.eolcum.evocenter.ActionBuffer;
import com.turkcell.dv.dao.BusinessProcessDAO;
import com.turkcell.dv.dao.PrivilegeDAO;
import com.turkcell.dv.dao.ProcessEndpointDAO;
import com.turkcell.dv.dao.ProcessPrivilegeDAO;
import com.turkcell.dv.dao.UserDAO;
import com.turkcell.dv.dao.UserPrivilegeDAO;
import com.turkcell.dv.model.BusinessProcessDOM;
import com.turkcell.dv.model.PrivilegeDOM;
import com.turkcell.dv.model.ProcessPrivilegeDOM;
import com.turkcell.dv.model.UserDOM;
import com.turkcell.dv.model.UserPrivilegeDOM;
import com.turkcell.dv.rest.dto.BusinessProcessDTO;
import com.turkcell.dv.rest.dto.PrivilegeDTO;
import com.turkcell.dv.rest.dto.UserDTO;
import com.turkcell.dv.service.RequestScopedContext;

@RestController
@RequestMapping(value = "/UserService", headers = "Content-Type=application/json", consumes = "application/json", produces = "application/json")
public class UserService {

	@Autowired private UserDAO userDAO;
	@Autowired private BusinessProcessDAO businessProcessDAO;
	@Autowired private UserPrivilegeDAO userPrivilegeDAO;
	@Autowired private ProcessEndpointDAO businessProcessEndpointDAO;
	@Autowired private PrivilegeDAO privilegeDAO;
	@Autowired private ProcessPrivilegeDAO processPrivilegeDAO;
	@Autowired private RequestScopedContext rsc;
	@Autowired private ActionBuffer buffer;
	@Value("${EvoCenter_API_URL}")  private String EvoCenter_API_URL;
	
	@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
	public UserDOM create(@RequestBody @Valid UserDOM user) {
		return userDAO.addUser(user);
	}

	@RequestMapping(method = RequestMethod.GET)
	public @ResponseBody List<UserDTO> list() {
		List<UserDOM> users = userDAO.listUsers();
		ArrayList<UserDTO> userDTOList = new ArrayList<UserDTO>();
		for (int i = 0; i < users.size(); i++) {
			UserDTO uDTO = new UserDTO();
			uDTO.transformDOM(users.get(i));
			userDTOList.add(uDTO);
		}
		return userDTOList;
	}

	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	public @ResponseBody UserDTO get(@PathVariable("id") long id) {

		UserDTO user = new UserDTO();
		user.transformDOM(userDAO.getUserById(id));
		return user;
	}

	@RequestMapping(value = "username/{username}", method = RequestMethod.GET)
	public @ResponseBody UserDTO getUserByUsername(@PathVariable("username") String username) {
		UserDTO user = new UserDTO();
		user.transformDOM(userDAO.getUserByUsername(username));
		return user;
	}

	@RequestMapping(value = "getLoggedUser", method = RequestMethod.GET)
	public @ResponseBody UserDTO getLoggedUser() {
		UserDTO user = new UserDTO();
		user.transformDOM(userDAO.getUserById(rsc.getUserId()));
		List<Action> actionList = buffer.getActionList(rsc.getUserId().toString());
		
		Action a = new Action();
		a.setActionType(Action.ACTION_TYPE_POLLING);
		a.setTimeStamp(Calendar.getInstance().getTimeInMillis());
		a.setAction(Action.ACTION_GET_APARTMENT_INFO);
		a.setResponseURL(EvoCenter_API_URL + "/apartmentService/setApartmentInfo");
		boolean found = false;
		for(int i = 0; i < actionList.size(); i++) {
			if(actionList.get(i).getAction() == Action.ACTION_GET_APARTMENT_INFO) {
				found = true;
				actionList.set(i, a);
				break;
			}
		}
		if(!found) {
			actionList.add(a);
		}
		return user;
	}

	@RequestMapping(value = "getPrivilegesOfLoggedUser", method = RequestMethod.GET)
	public @ResponseBody List<PrivilegeDTO> getPrivilegesOfLoggedUser() {
		List<PrivilegeDTO> privilegeDTOList = new ArrayList<PrivilegeDTO>();
		UserDOM u = userDAO.getUserById(rsc.getUserId());
		List<UserPrivilegeDOM> upList = userPrivilegeDAO.listUserPrivilegesByUserId(u.getId());
		List<PrivilegeDOM> pList = privilegeDAO.listPrivileges();

		for (int i = 0; i < pList.size(); i++) {
			boolean exist = false;
			for (int j = 0; j < upList.size(); j++) {
				exist = upList.get(j).getPrivilegeId() == pList.get(i).getId();
				if (exist)
					break;
			}
			if (!exist) {
				pList.remove(i);
				i--;
			}
		}
		for (int i = 0; i < pList.size(); i++) {
			PrivilegeDTO pDTO = new PrivilegeDTO();
			pDTO.transformDOM(pList.get(i));
			privilegeDTOList.add(pDTO);
		}
		return privilegeDTOList;
	}

	@RequestMapping(value = "getBusinessProcessesOfLoggedUser", method = RequestMethod.GET)
	public @ResponseBody List<BusinessProcessDTO> getBusinessProcessesOfLoggedUser() {
		List<BusinessProcessDTO> businessProcessList = new ArrayList<BusinessProcessDTO>();
		List<PrivilegeDTO> privilegeDTOList = getPrivilegesOfLoggedUser();

		for (int i = 0; i < privilegeDTOList.size(); i++) {
			List<BusinessProcessDTO> bpList = getBusinessProcessListByPrivilegeId(privilegeDTOList.get(i).getId());
			for (int j = 0; j < bpList.size(); j++) {
				businessProcessList.add(bpList.get(j));
			}
		}
		// Remove Duplicates
		for (int i = 0; i < businessProcessList.size(); i++) {
			int count = 0;
			for (int j = 0; j < businessProcessList.size(); j++) {
				if (businessProcessList.get(i).getId() == businessProcessList.get(j).getId()) {
					count++;
				}
				if (count > 1) {
					businessProcessList.remove(j);
					j--;
				} 
			}
		}
		return businessProcessList;
	}

	@RequestMapping(value = "getBusinessProcessListByPrivilegeId", method = RequestMethod.GET)
	public @ResponseBody List<BusinessProcessDTO> getBusinessProcessListByPrivilegeId(@PathVariable("privilegeId") Long privilegeId) {
		List<BusinessProcessDTO> businessProcessList = new ArrayList<BusinessProcessDTO>();

		List<ProcessPrivilegeDOM> processPrivilegeDOMList = processPrivilegeDAO.getBusinessProcessIdListByPrivilegeId(privilegeId);
		List<BusinessProcessDOM> businessProcessDOMList = new ArrayList<BusinessProcessDOM>();
		for (int i = 0; i < processPrivilegeDOMList.size(); i++) {
			BusinessProcessDOM bpDOM = businessProcessDAO.getBusinessProcessById(processPrivilegeDOMList.get(i).getProcessId());
			if (bpDOM != null) {
				businessProcessDOMList.add(bpDOM);
			}
		}
		// Remove Duplicate business processes
		for (int i = 0; i < businessProcessDOMList.size(); i++) {
			BusinessProcessDTO bpDTO = new BusinessProcessDTO();
			bpDTO.transformDOM(businessProcessDOMList.get(i));
			businessProcessList.add(bpDTO);

		}

		return businessProcessList;
	}

	@RequestMapping(value = "/{id}", method = RequestMethod.PUT)
	public @ResponseBody UserDOM update(@PathVariable("id") long id, @RequestBody @Valid UserDOM user) {
		return userDAO.updateUser(user);
	}

	@RequestMapping(value = "/{id}", method = RequestMethod.DELETE)
	public @ResponseBody ResponseEntity<Boolean> delete(@PathVariable("id") long id) {
		userDAO.removeUser(id);
		return new ResponseEntity<Boolean>(Boolean.TRUE, HttpStatus.OK);
	}
}
